import * as THREE from 'three';
import { BaseDemo } from './BaseDemo';
import GUI from "three/examples/jsm/libs/lil-gui.module.min.js";

export class DemoManager {
    private demos: Map<string, BaseDemo> = new Map();
    private currentDemo?: BaseDemo;
    private scene: THREE.Scene;
    private gui: GUI;
    private mainFolder: GUI;
    private stats: {
        fps: number;
        particleCount: number;
        activeEmitters: number;
    } = { fps: 0, particleCount: 0, activeEmitters: 0 };

    constructor(scene: THREE.Scene, gui: GUI) {
        this.scene = scene;
        this.gui = gui;
        this.mainFolder = gui.addFolder('Demo Manager');
        this.setupMainControls();
        this.setupStatsDisplay();
    }

    /**
     * 注册demo
     */
    registerDemo(demo: BaseDemo): void {
        this.demos.set(demo.name, demo);
        demo.init();
    }

    /**
     * 切换到指定demo
     */
    switchToDemo(demoName: string): boolean {
        const demo = this.demos.get(demoName);
        if (!demo) {
            console.warn(`Demo "${demoName}" not found`);
            return false;
        }

        // 停用当前demo
        if (this.currentDemo) {
            this.currentDemo.deactivate();
        }

        // 激活新demo
        this.currentDemo = demo;
        demo.activate();
        demo.setupGUI(this.gui);

        console.log(`Switched to demo: ${demoName}`);
        return true;
    }

    /**
     * 获取所有demo名称
     */
    getDemoNames(): string[] {
        return Array.from(this.demos.keys());
    }

    /**
     * 获取当前demo
     */
    getCurrentDemo(): BaseDemo | undefined {
        return this.currentDemo;
    }

    /**
     * 更新当前demo
     */
    update(deltaTime: number): void {
        if (this.currentDemo) {
            this.currentDemo.update(deltaTime);
            this.updateStats();
        }
    }

    /**
     * 设置主控制面板
     */
    private setupMainControls(): void {
        const controls = {
            currentDemo: '',
            reset: () => {
                if (this.currentDemo) {
                    this.currentDemo.reset();
                }
            },
            switchDemo: (demoName: string) => {
                this.switchToDemo(demoName);
                controls.currentDemo = demoName;
            }
        };

        // 等待demos注册后再添加选择器 这算是黑盒写法了吧，这意思反正就是实例化之后，肯定会注册所有的demo
        setTimeout(() => { 
            const demoNames = this.getDemoNames();
            if (demoNames.length > 0) {
                controls.currentDemo = demoNames[0];
                this.mainFolder.add(controls, 'currentDemo', demoNames)
                    .name('当前Demo')
                    .onChange((value: string) => {
                        this.switchToDemo(value);
                    });
                
                this.mainFolder.add(controls, 'reset').name('重置Demo');
                
                // 默认激活第一个demo
                this.switchToDemo(demoNames[0]);
            }
        }, 100);
    }

    /**
     * 设置统计信息显示
     */
    private setupStatsDisplay(): void {
        const statsFolder = this.mainFolder.addFolder('统计信息');
        statsFolder.add(this.stats, 'fps').name('FPS').listen();
        statsFolder.add(this.stats, 'particleCount').name('粒子数量').listen();
        statsFolder.add(this.stats, 'activeEmitters').name('活跃发射器').listen();
        statsFolder.open();
    }

    /**
     * 更新统计信息
     */
    private updateStats(): void {
        if (this.currentDemo && this.currentDemo.particleSystem) {
            let totalParticles = 0;
            let activeEmitters = 0;

            this.currentDemo.particleSystem.emitters.forEach(emitter => {
                totalParticles += emitter.particles.size;
                if (emitter.emitterLife > 0) {
                    activeEmitters++;
                }
            });

            this.stats.particleCount = totalParticles;
            this.stats.activeEmitters = activeEmitters;
        }
    }

    /**
     * 设置FPS
     */
    setFPS(fps: number): void {
        this.stats.fps = Math.round(fps);
    }

    /**
     * 清理所有资源
     */
    dispose(): void {
        this.demos.forEach(demo => demo.dispose());
        this.demos.clear();
        this.mainFolder.destroy();
    }

    /**
     * 导出当前demo配置
     */
    exportConfig(): string {
        if (!this.currentDemo) return '{}';
        
        const config = {
            demoName: this.currentDemo.name,
            // 这里可以添加更多配置项
        };
        
        return JSON.stringify(config, null, 2);
    }

    /**
     * 导入demo配置
     */
    importConfig(configJson: string): boolean {
        try {
            const config = JSON.parse(configJson);
            if (config.demoName) {
                return this.switchToDemo(config.demoName);
            }
            return false;
        } catch (error) {
            console.error('Failed to import config:', error);
            return false;
        }
    }
}